<template>
  <div class="trigger-context" ref="triggerContextRef">
    <slot></slot>
  </div>
</template>
<script lang="ts" setup>
import { onMounted, ref, onUnmounted, getCurrentInstance } from "vue";
import type { Component } from "vue";
import { popUp } from "./utils/popUp";

interface Props {
  trigger?: "click" | "rightClick" | "hover" | "manual";
  component?: Component;
  props?: Record<string, any>;
  direction?: "top" | "bottom" | "left" | "right";
  type?: "dialog" | "popover";
  options?: Record<string, any>;
}

const props = withDefaults(defineProps<Props>(), {
  trigger: "click"
});
const parentInstance = getCurrentInstance();
const emits = defineEmits(["open", "close"]);
const triggerContextRef = ref<HTMLDivElement>();
const expose: any = {};

const close = () => {
  emits("close");
};

const eventMapping: Record<string, any> = {
  click: {
    __handler__: (e: MouseEvent) => {
      e.preventDefault();
      e.stopPropagation();
      const { x, y, height, width, bottom } = e.currentTarget?.getBoundingClientRect();
      const { remove } = popUp(
        {
          parentInstance,
          direction: props.direction,
          location: { x, y, height, width, bottom },
          props: { ...props.props },
          type: props.type,
          options: props.options,
          close
        },
        props.component
      );
      expose.remove = remove;
      emits("open");
    },
    addEvent: () => {
      triggerContextRef.value?.addEventListener("click", eventMapping[props.trigger].__handler__);
    },
    removeEvent: () => {
      triggerContextRef.value?.removeEventListener("click", eventMapping[props.trigger].__handler__);
    }
  },
  rightClick: ["contextmenu"],
  hover: ["mouseenter", "mouseleave"]
};

onUnmounted(() => {
  if (props.trigger === "manual") return;
  eventMapping[props.trigger].removeEvent();
});
onMounted(() => {
  if (props.trigger === "manual") return;
  eventMapping[props.trigger].addEvent();
});

const manualTrigger = (e: any) => {
  if (props.trigger === "manual") {
    eventMapping["click"].__handler__(e);
  }
};

defineExpose({
  ...expose,
  manualTrigger
});
</script>
<style lang="scss" scoped></style>
